package com.guigusuqi.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guigusuqi.commonutils.utils.GetTokenByAuthorizationUtils;
import com.guigusuqi.commonutils.utils.JWTUtils;
import com.guigusuqi.commonutils.utils.RedisCache;
import com.guigusuqi.commonutils.vo.Result;
import com.guigusuqi.user.dto.UserLoginDTO;
import com.guigusuqi.user.entity.LoginUser;
import com.guigusuqi.user.entity.SysRole;
import com.guigusuqi.user.entity.SysUser;
import com.guigusuqi.user.entity.SysUserRole;
import com.guigusuqi.user.mapper.SysUserMapper;
import com.guigusuqi.user.service.SysRoleService;
import com.guigusuqi.user.service.SysUserRoleService;
import com.guigusuqi.user.service.SysUserService;
import com.guigusuqi.user.vo.SysUserVO;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService
{
    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private AuthenticationManager authenticationManager;

    @Resource
    private RedisCache redisCache;

    @Resource
    private SysRoleService sysRoleService;

    @Resource
    private SysUserRoleService sysUserRoleService;

    @Override
    public Result login(UserLoginDTO userLoginDTO)
    {
        if (StringUtils.isEmpty(userLoginDTO.getPhone()) || StringUtils.isEmpty(userLoginDTO.getPassword()))
        {
            return Result.fail().message("手机号或者密码不能为空!");
        }

        //  通过手机号获取用户信息
        SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhone, userLoginDTO.getPhone()));

        //  通过UsernamePasswordAuthenticationToken获取用户名和密码
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(sysUser.getUserId(), userLoginDTO.getPassword());

        //  AuthenticationManager委托机制对authenticationToken 进行用户认证
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);

        if(Objects.isNull(authenticate))
        {
            throw new RuntimeException("认证失败");
        }
        //  如果认证通过,使用user生成jwt jwt存入Redis 返回

        //  如果authenticationManager认证通过，拿到这个当前登录用户信息
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();

        //  获取当前用户的userId
        String userId = loginUser.getUser().getUserId();

        //  通过jwt获取token,再存入redis中
        String token = JWTUtils.createToken(userId);
        redisCache.setCacheObject("TOKEN_"+token,loginUser,7, TimeUnit.HOURS);

        return Result.success().data(token);
    }

    /**
     * token合法性校验
     * 是否为空、解析是否成功、redis是否存在
     * @param token
     * @return
     */
    @Override
    public LoginUser checkAndParseToken(String token)
    {
        if (StringUtils.isEmpty(token))
        {
            return null;
        }
        /*解析token*/
        Map<String, Object> stringObjectMap = JWTUtils.checkToken(token);
        if (stringObjectMap == null) {
            return null;
        }
        LoginUser loginUser = redisCache.getCacheObject("TOKEN_" + token);
        if(Objects.isNull(loginUser))
        {
            return null;
        }
        return loginUser;
    }

    //  获取用户对应角色名
    public String getRoleByUserId(String userId)
    {
        System.out.println("*************");
        System.out.println(userId);
        System.out.println("*************");
        return sysRoleService.getOne(new LambdaQueryWrapper<SysRole>().
                eq(SysRole::getRoleId,
                        sysUserRoleService.
                                getOne(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId)).getRoleId())).getRoleName();
    }

    @Override
    public Result logout() {
        boolean b = false;
        String token = GetTokenByAuthorizationUtils.getToken();
        b = redisCache.deleteObject("TOKEN_" + token);
        return b ? Result.success().message("退出登录成功！") :
                Result.fail().message("退出登录失败！");
    }

    public SysUser findOneUserByName(String userName)
    {
        return sysUserMapper.selectOneUserByName(userName);
    }

    @Override
    public HashMap<String, Object> setVariables(String userId)
    {
        LambdaQueryWrapper<SysUser> sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysUserLambdaQueryWrapper.ne(SysUser::getUserId, userId);
        List<SysUser> sysUsers = sysUserMapper.selectList(sysUserLambdaQueryWrapper);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("assignee0",userId);
        hashMap.put("assignee1",sysUsers.get(0).getUserId());
        hashMap.put("assignee2",sysUsers.get(1).getUserId());
        hashMap.put("assignee3",sysUsers.get(2).getUserId());

        return hashMap;
    }
}
